package com.huanxing.cloud.product.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huanxing.cloud.common.core.constant.CommonConstants;
import com.huanxing.cloud.common.security.entity.HxUser;
import com.huanxing.cloud.common.security.util.SecurityUtils;
import com.huanxing.cloud.product.api.constant.ProductConstants;
import com.huanxing.cloud.product.api.entity.*;
import com.huanxing.cloud.product.mapper.*;
import com.huanxing.cloud.product.service.IGoodsSpuService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

/**
 * 商品spu
 *
 * @author lijx
 * @since 2022/2/22 15:27
 */
@Service
@AllArgsConstructor
public class GoodsSpuServiceImpl extends ServiceImpl<GoodsSpuMapper, GoodsSpu> implements IGoodsSpuService {

	private final GoodsSkuMapper goodsSkuMapper;

	private final GoodsSpuSpecsMapper goodsSpuSpecsMapper;

	private final GoodsSkuSpecsValueMapper goodsSkuSpecsValueMapper;

	private final GoodsCollectMapper goodsCollectMapper;

	private final GoodsFootprintMapper goodsFootprintMapper;

	@Override
	public IPage<GoodsSpu> adminPage(Page page, GoodsSpu goodsSpu) {
		return baseMapper.selectPageByAdmin(page, goodsSpu);
	}

	@Override
	public IPage<GoodsSpu> warehousePage(Page page, GoodsSpu goodsSpu) {
		return baseMapper.selectPageWarehouse(page, goodsSpu);
	}

	@Override
	public GoodsSpu getSpuById(String id) {
		return baseMapper.selectSpuById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateGoods(GoodsSpu goodsSpu) {

		List<GoodsSku> goodsSkuList = goodsSpu.getGoodsSkus();
		goodsSpu.setHighPrice(
				goodsSkuList.stream().max(Comparator.comparing(GoodsSku::getSalesPrice)).get().getSalesPrice());
		goodsSpu.setLowPrice(
				goodsSkuList.stream().min(Comparator.comparing(GoodsSku::getSalesPrice)).get().getSalesPrice());
		List<String> notDelSkuIds = new ArrayList<>();
		// 保存sku
		goodsSkuList.forEach(goodsSku -> {
			goodsSku.setSpuId(goodsSpu.getId());
			if (StringUtils.hasText(goodsSku.getId())) {
				goodsSkuMapper.updateById(goodsSku);
			}
			else {
				goodsSkuMapper.insert(goodsSku);
			}
			notDelSkuIds.add(goodsSku.getId());
		});
		// sku处理
		goodsSkuMapper.delete(Wrappers.<GoodsSku>lambdaQuery()
			.eq(GoodsSku::getSpuId, goodsSpu.getId())
			.notIn(!CollectionUtils.isEmpty(notDelSkuIds), GoodsSku::getId, notDelSkuIds.toArray()));

		// 删除多规格
		goodsSpuSpecsMapper.delete(Wrappers.<GoodsSpuSpecs>lambdaQuery().eq(GoodsSpuSpecs::getSpuId, goodsSpu.getId()));
		goodsSkuSpecsValueMapper
			.delete(Wrappers.<GoodsSkuSpecsValue>lambdaQuery().eq(GoodsSkuSpecsValue::getSpuId, goodsSpu.getId()));
		// 多规格处理
		if (CommonConstants.YES.equals(goodsSpu.getEnableSpecs())) {
			this.addSpecs(goodsSpu);
		}
		goodsSpu.setVerifyStatus(ProductConstants.VERIFY_STATUS_WAIT);
		super.updateById(goodsSpu);
		return Boolean.TRUE;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean saveGoods(GoodsSpu goodsSpu) {
		List<GoodsSku> goodsSkuList = goodsSpu.getGoodsSkus();

		goodsSpu.setHighPrice(
				goodsSkuList.stream().max(Comparator.comparing(GoodsSku::getSalesPrice)).get().getSalesPrice());
		goodsSpu.setLowPrice(
				goodsSkuList.stream().min(Comparator.comparing(GoodsSku::getSalesPrice)).get().getSalesPrice());
		goodsSpu.setVerifyStatus(ProductConstants.VERIFY_STATUS_WAIT);
		super.save(goodsSpu);
		// 保存sku
		goodsSkuList.forEach(goodsSku -> {
			goodsSku.setId(null);
			goodsSku.setSpuId(goodsSpu.getId());
			goodsSkuMapper.insert(goodsSku);
		});
		// 多规格处理
		if (CommonConstants.YES.equals(goodsSpu.getEnableSpecs())) {
			this.addSpecs(goodsSpu);
		}

		return Boolean.TRUE;
	}

	private void addSpecs(GoodsSpu goodsSpu) {
		List<GoodsSpuSpecs> goodsSpuSpecsList = goodsSpu.getGoodsSpuSpecs();
		for (int i = 0; i < goodsSpuSpecsList.size(); i++) {
			GoodsSpuSpecs goodsSpuSpecs = goodsSpuSpecsList.get(i);
			if (ObjectUtil.isNotNull(goodsSpuSpecs)) {
				goodsSpuSpecs.setId(null);
				goodsSpuSpecs.setSort(i);
				goodsSpuSpecs.setSpuId(goodsSpu.getId());
				goodsSpuSpecsMapper.insert(goodsSpuSpecs);
			}
		}
		// 保存sku规格值
		List<GoodsSku> goodsSkus = goodsSpu.getGoodsSkus();
		goodsSkus.forEach(goodsSku -> {
			List<GoodsSkuSpecsValue> goodsSkuSpecsValues = goodsSku.getGoodsSkuSpecsValues();
			for (int j = 0; j < goodsSkuSpecsValues.size(); j++) {
				GoodsSkuSpecsValue goodsSkuSpecsValue = goodsSkuSpecsValues.get(j);
				if (ObjectUtil.isNotNull(goodsSkuSpecsValue)) {
					goodsSkuSpecsValue.setId(null);
					goodsSkuSpecsValue.setSort(j);
					goodsSkuSpecsValue.setSkuId(goodsSku.getId());
					goodsSkuSpecsValue.setSpuId(goodsSku.getSpuId());
					goodsSkuSpecsValueMapper.insert(goodsSkuSpecsValue);
				}
			}
		});
	}

	@Override
	public IPage<GoodsSpu> apiPage(Page page, GoodsSpu goodsSpu) {
		return baseMapper.selectApiPage(page, goodsSpu);
	}

	@Override
	public GoodsSpu getApiSpuById(String id) {
		GoodsSpu goodsSpu = baseMapper.selectApiSpuById(id);
		if (Objects.nonNull(goodsSpu)) {
			HxUser hxUser = SecurityUtils.getUser();
			if (Objects.nonNull(hxUser) && StringUtils.hasText(hxUser.getUserId())) {
				GoodsCollect goodsCollect = goodsCollectMapper.selectOne(Wrappers.<GoodsCollect>lambdaQuery()
					.eq(GoodsCollect::getSpuId, id)
					.eq(GoodsCollect::getUserId, hxUser.getUserId()));
				if (Objects.nonNull(goodsCollect)) {
					goodsSpu.setCollectId(goodsCollect.getId());
				}
				// 保存浏览记录
				GoodsFootprint goodsFootprint = new GoodsFootprint();
				goodsFootprint.setSpuId(id);
				goodsFootprint.setUserId(hxUser.getUserId());
				goodsFootprintMapper.insert(goodsFootprint);
			}

		}
		return goodsSpu;
	}

	@Override
	public boolean updateSalesVolume(String spuId, Integer buyQuantity) {
		return baseMapper.update(new GoodsSpu(),
				Wrappers.<GoodsSpu>lambdaUpdate()
					.eq(GoodsSpu::getId, spuId)
					.setSql(" sales_volume = sales_volume + " + buyQuantity)) > 0;
	}

	@Override
	public List<GoodsSpu> listByShopIds(List<String> ids) {
		return baseMapper.listByShopIds(ids);
	}

}
